﻿using Mapster;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Bcpg;
using Org.BouncyCastle.Utilities;
using SqlSugar;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Zhaoxi.SqlSugar.Common;
using Zhaoxi.SqlSugar.DTOModels;
using Zhaoxi.SqlSugar.Models;
using static System.Net.Mime.MediaTypeNames;
using static System.Reflection.Metadata.BlobBuilder;
using DbType = SqlSugar.DbType;

namespace Zhaoxi.SqlSugarAdvanced
{
    public class QueryOperationInfo
    {
        #region 简单查询 - 单表查询
        /// <summary>
        /// 简单查询 - 单表查询
        /// </summary>
        public static void SimpleQueryShow()
        {
            ConnectionConfig connectionConfig = new ConnectionConfig() // 连接配置
            {
                ConnectionString = CustomConnectionConfig.ConnectionString001, // 数据库连接字符串
                IsAutoCloseConnection = true, // 自动关闭连接
                DbType = DbType.SqlServer // 数据库类型
            };
            using (SqlSugarClient db = new SqlSugarClient(connectionConfig)) // 创建SqlSugarClient实例
            {
                db.Aop // 配置生成SQL语句的日志输出
                    .OnLogExecuting = (s, p) => // 在执行SQL语句时触发
                {
                    Console.WriteLine("----------------------------");
                    Console.WriteLine($"Sql语句:{s}");
                };

                List<StudentInfo> addlist = new List<StudentInfo>();
                for (int i = 0; i < 500; i++)
                {
                    addlist.Add(new StudentInfo()
                    {
                        Id = i + 1,
                        CreateTime = DateTime.Now,
                        Isdeleted = false,
                        Name = $"名称_{i + 1}",
                        SchoolId = i + 1,
                    });
                }
                db.Deleteable<StudentInfo>() // 删除表中的所有数据
                    .ExecuteCommand(); // 清空表数据
                db.Insertable<StudentInfo>(addlist) // 批量插入数据
                    .ExecuteCommand(); // 执行插入操作


                //查询集合-//select * from StudentInfo
                List<StudentInfo> list = db.Queryable<StudentInfo>() // 查询StudentInfo表中的所有数据
                    .ToList(); // 返回一个StudentInfo类型的列表

                //查询总数
                int count = db.Queryable<StudentInfo>() // 查询StudentInfo表中的数据
                    .Count(); // 返回数据的总数
                //select count(1) from StudentInfo

                List<StudentInfo> studentList;
                //按条件查询
                {
                    studentList = db.Queryable<StudentInfo>() // 查询StudentInfo表中的数据
                        .Where(it => it.Id == 1) // 条件查询，Id等于1
                        .ToList(); // 返回一个StudentInfo类型的列表  
                    //select * from StudentInfo where id=1

                    studentList = db.Queryable<StudentInfo>() // 查询StudentInfo表中的数据
                        .Where(it => it.Name != null) // 条件查询，Name不为null
                        .ToList(); // 返回一个StudentInfo类型的列表
                    //不是null
                    //select * from StudentInfo where name is not null

                    studentList = db.Queryable<StudentInfo>() // 查询StudentInfo表中的数据
                        .Where(it => it.Name == null) // 条件查询，Name为null
                        .ToList(); // 返回一个StudentInfo类型的列表
                    //是null                                                                    
                    //select * from StudentInfo where name is null

                    studentList = db.Queryable<StudentInfo>() // 查询StudentInfo表中的数据
                        .Where(it => it.Name != "名称_11") // 条件查询，Name不等于"名称_11"
                        .ToList(); // 返回一个StudentInfo类型的列表
                    //不是空 ,不为空      
                    //select * from StudentInfo where name <> ''
                }

                //多条件查询 
                {
                    studentList = db.Queryable<StudentInfo>() // 查询StudentInfo表中的数据
                        .Where(it => it.Id > 10 && it.Name == "名称_11") // 条件查询，Id大于10且Name等于"名称_11"
                        .ToList(); // 返回一个StudentInfo类型的列表

                    //select * from StudentInfo where id>10 and name='a'
                    studentList = db.Queryable<StudentInfo>() // 查询StudentInfo表中的数据
                        .Where(it => it.Id > 10) // 条件查询，Id大于10
                        .Where(it => it.Name == "名称_11")// 条件查询，Name等于"名称_11"
                        .ToList();// 返回一个StudentInfo类型的列表
                }

                //动态OR查询 - 表达式用于动态增加查询条件的
                {
                    Expressionable<StudentInfo> exp = Expressionable.Create<StudentInfo>(); // 创建一个表达式构建器
                    string name = "名称_11";

                    //.OrIf 是条件成立才会拼接OR 
                    exp.OrIF(!string.IsNullOrWhiteSpace(name), it => it.Name.Contains(name));// 如果name不为空，则添加条件Name包含name的查询

                    //拼接OR 或者条件拼接
                    exp.Or(it => it.Name.Contains("名称_"));// 添加条件Name包含"名称_"的查询
                    studentList = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Where(exp.ToExpression())// 使用构建好的表达式进行查询
                        .ToList();// 返回一个StudentInfo类型的列表
                }

                //模糊查询
                {
                    studentList = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Where(it => it.Name.Contains("名称_"))// 条件查询，Name包含"名称_"
                        .ToList();// 返回一个StudentInfo类型的列表
                    //select  * from  StudentInfo where name like %jack%
                }

                //根据主键查询
                {
                    /*单主键查询*/
                    //通过主键查询 SingleById
                    db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .InSingle(2);// 根据主键Id查询单条记录

                    //根据ID查询
                    //select * from StudentInfo where id=2
                    db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Single(it => it.Id == 2);// 根据Id查询单条记录


                    /*多主键查询*/
                    var getAll = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .WhereClassByPrimaryKey(new StudentInfo() { Id = 123 })//单个实体查询
                        .ToList(); //单个实体  

                    getAll = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .WhereClassByPrimaryKey(new List<StudentInfo>()//集合实体查询
                        {
                            new StudentInfo() { Id = 123 },
                            new StudentInfo() { Id = 234 },
                            new StudentInfo() { Id = 345 }

                        }).ToList(); //支持集合
                }

                //查询第一条 ，第一行
                {
                    //First() 等同于C#中的 FirstOrDefault , 没有值返回 null
                    //没有返回Null
                    StudentInfo student = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .First(it => it.Id == 1);// 根据Id查询第一条记录
                }

                {
                    //没有返回Null
                    //select top 1 * from StudentInfo order by id desc where id=1
                    StudentInfo student = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                      .OrderBy(it => it.Id, OrderByType.Desc)// 按Id降序排序
                      .First(it => it.Id == 1);// 根据Id查询第一条记录
                }

                //查前几条 
                {
                    List<StudentInfo> studetntlist = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Take(10)// 取前10条记录
                        .ToList();// 返回一个StudentInfo类型的列表
                }

                //数据行数
                {
                    int count1 = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Where(it => it.Id > 11)// 条件查询，Id大于11
                        .Count();//同步 返回满足条件的记录数

                    Task<int> countTask = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Where(it => it.Id > 11)// 条件查询，Id大于11
                        .CountAsync();//异步 返回满足条件的记录数
                    //异步
                    //select count(*) from StudentInfo where id>11
                    //你也可以用函数
                    //SqlFunc.AggregateCount
                }



                //是否存在记录
                {
                    db.Close();
                    db.Open();
                    bool isExists = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Where(it => it.Id > 11)// 条件查询，Id大于11
                        .Any();//是否存在记录

                    isExists = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Any(it => it.Id > 11); // 条件查询，Id大于11 的是否存在
                }

                //In查询,IN的使用
                {
                    int[] allIds = new int[] { 2, 3, 31 };
                    List<StudentInfo> list1 = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Where(it => allIds.Contains(it.Id))// 条件查询，Id在allIds数组中
                        .ToList();// 返回一个StudentInfo类型的列表

                    //字符串类型 varchar和nvarchar (默认varchar来保证性能)
                    //NameList.Contains(it.Name, true) //true和false来控制是varchar还是nvarchar
                }
                //多个字段 条件拼接
                {
                    List<StudentInfo> OrderList = new List<StudentInfo>()
                    {
                        new StudentInfo{ Id = 1,Name="名称_1"},
                        new StudentInfo{ Id = 2,Name="名称_2"},
                        new StudentInfo{ Id = 3,Name="名称_3"}
                    };
                    Expressionable<StudentInfo> exp = new Expressionable<StudentInfo>();
                    foreach (var item in OrderList)
                    {
                        exp.Or(it => it.Id == item.Id && it.Name == item.Name);// 拼接多个条件
                    }
                    //使用构造好的表达式
                    var studentlist = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Where(exp.ToExpression())// 使用构建好的表达式进行查询
                        .ToList();// 返回一个StudentInfo类型的列表
                }


                //使用 in 的模糊查询
                {
                    var names = new string[] { "名称_", "名称_11" };
                    Expressionable<StudentInfo> exp = new Expressionable<StudentInfo>();
                    foreach (var item in names)
                    {
                        exp.Or(it => it.Name.Contains(item));// 拼接多个模糊查询条件
                    }
                    var studentlist = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Where(exp.ToExpression())// 使用构建好的表达式进行查询
                        .ToList();// 返回一个StudentInfo类型的列表
                }

                //NOT IN
                {
                    int[] allIds = new int[] { 2, 3, 31 };
                    var studentlist = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Where(it => !allIds.Contains(it.Id))// 条件查询，Id不在allIds数组中
                        .ToList();// 返回一个StudentInfo类型的列表
                }

                //简单排序
                {
                    var studentlist = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .OrderBy(st => st.Id, OrderByType.Desc)// 按Id降序排序
                        .ToList();// 返回一个StudentInfo类型的列表
                }

                //查询一列
                {
                    //单值 查询列 查询单独列
                    var studentlist = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Select(it => it.Name)// 选择Name列
                        .ToList();// 返回一个字符串类型的列表
                }

                //查询单条
                {
                    StudentInfo student = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Single(it => it.Id == 1);// 根据Id查询单条记录
                    //没有返回Null，如果结果大于1条会抛出错误
                    //select * from StudentInfo where id=1 // 查询id等于1的单条记录
                }

                //获取最大值,最小值
                {


                    int maxNum = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Max(it => it.Id);// 同步 返回Id的最大值

                    Task<int> maxTask = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .MaxAsync(it => it.Id);// 异步 返回Id的最大值


                    db.Close();
                    db.Open();

                    int minNum = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Min(it => it.Id);// 同步 返回Id的最小值
                    Task<int> minTask = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .MinAsync(it => it.Id);// 异步 返回Id的最小值
                }

                //求和
                {
                    db.Close();
                    db.Open();
                    int sumNum = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .Sum(it => it.Id);// 同步 返回Id的总和

                    Task<int> sumTask = db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .SumAsync(it => it.Id);// 异步 返回Id的总和
                }
                //查询过滤排除某一个字段
                {
                    /***单表***/
                    db.Close();
                    db.Open();
                    db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .ToList();// 返回一个StudentInfo类型的列表
                    db.Queryable<StudentInfo>()// 查询StudentInfo表中的数据
                        .IgnoreColumns(it => it.Name)// 忽略Name列
                        .ToList();//只支持单表查询 
                }
            }
        }
        #endregion

        #region 连接查询--多表查询
        /// <summary>
        /// 连接查询--多表查询
        /// </summary>
        public static void LinkQueryShow()
        {
            ConnectionConfig connectionConfig = new ConnectionConfig() // 连接配置
            {
                ConnectionString = CustomConnectionConfig.ConnectionString001,// 数据库连接字符串
                IsAutoCloseConnection = true,// 自动关闭连接
                DbType = DbType.SqlServer// 数据库类型
            };
            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))// 创建SqlSugarClient实例
            {
                db.CodeFirst.InitTables<Company>();// 初始化Company表
                db.CodeFirst.InitTables<User>();// 初始化User表
                db.CodeFirst.InitTables<UserScore>();// 初始化UserScore表
                db.Deleteable<UserScore>()// 删除UserScore表中的所有数据
                    .ExecuteCommand();// 执行命令
                db.Deleteable<Company>()// 删除Company表中的所有数据
                    .ExecuteCommand();// 执行命令
                db.Deleteable<User>()// 删除User表中的所有数据
                    .ExecuteCommand();// 执行命令

                #region 初始化数据
                List<Company> companyList = new List<Company>();
                for (int i = 0; i < 3; i++)
                {
                    companyList.Add(new Company()
                    {
                        CreateTime = DateTime.Now,
                        Id = i + 1,
                        CompanyName = $"朝夕教育_{i + 1}"
                    });
                }
                db.Insertable<Company>(companyList)// 批量插入Company数据
                    .ExecuteCommand();// 执行命令
                List<User> userList = new List<User>();

                List<UserScore> userScoreList = new List<UserScore>();
                for (int i = 0; i < 10; i++)
                {
                    userList.Add(new User()
                    {
                        CreateTime = DateTime.Now,
                        Id = i + 1,
                        UserName = $"用户_{i + 1}",
                        CompanyId = companyList[0].Id
                    });

                    userScoreList.Add(new UserScore()
                    {
                        UserId = i + 1,
                        Subject = "考勤",
                        Achievement = 90,
                        CreateTime = DateTime.Now
                    });

                    userScoreList.Add(new UserScore()
                    {
                        UserId = i + 1,
                        Subject = "绩效",
                        Achievement = 90,
                        CreateTime = DateTime.Now
                    });
                    userScoreList.Add(new UserScore()
                    {
                        UserId = i + 1,
                        Subject = "项目奖金",
                        Achievement = 89,
                        CreateTime = DateTime.Now
                    });

                }
                db.Insertable<User>(userList)// 批量插入User数据
                    .ExecuteCommand();// 执行命令
                db.Insertable<UserScore>(userScoreList)// 批量插入UserScore数据
                    .ExecuteCommand();// 执行命令
                #endregion

                //配置生成sql语句
                {
                    db.Aop // 在执行SQL语句时触发
                        .OnLogExecuting = (s, p) =>// 配置生成SQL语句的日志输出
                    {
                        Console.WriteLine("----------------------------");
                        Console.WriteLine($"Sql语句:{s}");
                    };
                }

                //左连接
                {
                    var query1 = db.Queryable<Company>()// 查询Company表中的数据
                               .LeftJoin<User>((c, u) => c.Id == u.CompanyId)// 左连接User表，连接条件为Company的Id等于User的CompanyId
                               .LeftJoin<UserScore>((c, u, us) => u.Id == us.UserId)// 左连接UserScore表，连接条件为User的Id等于UserScore的UserId
                               .Where(c => c.Id == 1)// 条件查询，Company的Id等于1
                               .Select((c, u, us) => new// 匿名类型
                               {
                                   CompanyId = c.Id,
                                   CompanyName = c.CompanyName,
                                   UserNae = u.UserName,
                                   Subject = us.Subject,
                                   ScoreCoutn = us.Achievement
                               })// 选择需要的字段
                               .ToList();// 返回一个匿名类型的列表

                    var query2 = db.Queryable<Company, User, UserScore>((c, u, us) =>
                                 new JoinQueryInfos(JoinType.Left, c.Id == u.CompanyId, JoinType.Left, u.Id == us.UserId
                             ))// 使用JoinQueryInfos进行左连接
                         .Where(c => c.Id == 1)// 条件查询，Company的Id等于1
                        .Select((c, u, us) => new// 匿名类型
                        {
                            CompanyId = c.Id,
                            CompanyName = c.CompanyName,
                            UserNae = u.UserName,
                            Subject = us.Subject,
                            ScoreCoutn = us.Achievement
                        })// 选择需要的字段
                        .ToList();// 返回一个匿名类型的列表
                }

                //右链接
                {
                    var query1 = db.Queryable<Company>()// 查询Company表中的数据
                                  .RightJoin<User>((c, u) => c.Id == u.CompanyId)// 右连接User表，连接条件为Company的Id等于User的CompanyId
                                  .RightJoin<UserScore>((c, u, us) => u.Id == us.UserId)// 右连接UserScore表，连接条件为User的Id等于UserScore的UserId
                                  .Where(c => c.Id == 1)// 条件查询，Company的Id等于1
                                  .Select((c, u, us) => new// 匿名类型
                                  {
                                      CompanyId = c.Id,
                                      CompanyName = c.CompanyName,
                                      UserNae = u.UserName,
                                      Subject = us.Subject,
                                      ScoreCoutn = us.Achievement
                                  })// 选择需要的字段
                                  .ToList();// 返回一个匿名类型的列表




                    var query2 = db.Queryable<Company, User, UserScore>((c, u, us) =>
                                    new JoinQueryInfos(JoinType.Right, c.Id == u.CompanyId, JoinType.Right, u.Id == us.UserId
                                ))// 使用JoinQueryInfos进行右连接
                            .Where(c => c.Id == 1)// 条件查询，Company的Id等于1
                           .Select((c, u, us) => new// 匿名类型
                           {
                               CompanyId = c.Id,
                               CompanyName = c.CompanyName,
                               UserNae = u.UserName,
                               Subject = us.Subject,
                               ScoreCoutn = us.Achievement
                           })// 选择需要的字段
                           .ToList();// 返回一个匿名类型的列表
                }

                //内连接
                {
                    var query1 = db.Queryable<Company>()// 查询Company表中的数据
                               .InnerJoin<User>((c, u) => c.Id == u.CompanyId)// 内连接User表，连接条件为Company的Id等于User的CompanyId
                               .InnerJoin<UserScore>((c, u, us) => u.Id == us.UserId)// 内连接UserScore表，连接条件为User的Id等于UserScore的UserId
                               .Where(c => c.Id == 1)// 条件查询，Company的Id等于1
                               .Select((c, u, us) => new// 匿名类型
                               {
                                   CompanyId = c.Id,
                                   CompanyName = c.CompanyName,
                                   UserNae = u.UserName,
                                   Subject = us.Subject,
                                   ScoreCoutn = us.Achievement
                               })// 选择需要的字段
                               .ToList();// 返回一个匿名类型的列表

                    var query2 = db.Queryable<Company, User, UserScore>((c, u, us) =>
                                 new JoinQueryInfos(JoinType.Inner, c.Id == u.CompanyId, JoinType.Inner, u.Id == us.UserId
                             ))// 使用JoinQueryInfos进行内连接
                         .Where(c => c.Id == 1)// 条件查询，Company的Id等于1
                        .Select((c, u, us) => new// 匿名类型
                        {
                            CompanyId = c.Id,
                            CompanyName = c.CompanyName,
                            UserNae = u.UserName,
                            Subject = us.Subject,
                            ScoreCoutn = us.Achievement
                        })// 选择需要的字段
                        .ToList();// 返回一个匿名类型的列表
                }

                //全连接
                {

                    var query1 = db.Queryable<Company>()// 查询Company表中的数据
                               .FullJoin<User>((c, u) => c.Id == u.CompanyId)// 全连接User表，连接条件为Company的Id等于User的CompanyId
                               .FullJoin<UserScore>((c, u, us) => u.Id == us.UserId)// 全连接UserScore表，连接条件为User的Id等于UserScore的UserId
                               .Where(c => c.Id == 1)// 条件查询，Company的Id等于1
                               .Select((c, u, us) => new// 匿名类型
                               {
                                   CompanyId = c.Id,
                                   CompanyName = c.CompanyName,
                                   UserNae = u.UserName,
                                   Subject = us.Subject,
                                   ScoreCoutn = us.Achievement
                               })// 选择需要的字段
                               .ToList();// 返回一个匿名类型的列表

                    var query2 = db.Queryable<Company, User, UserScore>((c, u, us) =>
                                 new JoinQueryInfos(JoinType.Full, c.Id == u.CompanyId, JoinType.Full, u.Id == us.UserId
                             ))// 使用JoinQueryInfos进行全连接
                         .Where(c => c.Id == 1)// 条件查询，Company的Id等于1
                        .Select((c, u, us) => new// 匿名类型
                        {
                            CompanyId = c.Id,
                            CompanyName = c.CompanyName,
                            UserNae = u.UserName,
                            Subject = us.Subject,
                            ScoreCoutn = us.Achievement
                        })// 选择需要的字段
                        .ToList();// 返回一个匿名类型的列表

                }

                //并集
                {
                    var q1 = db.Queryable<Student>()// 查询Student表中的数据
                   .Select(it => new User { UserName = it.Name });// 选择Name列并转换为User类型

                    var q2 = db.Queryable<User>()// 查询User表中的数据
                        .Select(it => new User { UserName = it.UserName });// 选择UserName列并转换为User类型

                    var list = db.UnionAll(q1, q2)// 使用UnionAll进行并集查询
                        .ToList();// 返回一个User类型的列表
                }
            }
            ;
        }
        #endregion

        #region 复杂查询-嵌套查询
        /// <summary>
        /// 复杂查询-嵌套查询
        /// </summary>
        public static void ComplexQueryShow()
        {
            ConnectionConfig connectionConfig = new ConnectionConfig() // 连接配置
            {
                ConnectionString = CustomConnectionConfig.ConnectionString001, // 数据库连接字符串
                IsAutoCloseConnection = true, // 自动关闭连接
                DbType = DbType.SqlServer // 数据库类型
            };
            using (SqlSugarClient db = new SqlSugarClient(connectionConfig)) // 创建SqlSugarClient实例
            {
                //配置生成sql语句
                {
                    db.Aop // 在执行SQL语句时触发
                        .OnLogExecuting = (s, p) => // 配置生成SQL语句的日志输出
                    {
                        Console.WriteLine("----------------------------");
                        Console.WriteLine($"Sql语句:{s}");
                    };
                }

                #region 初始化数据
                {
                    db.CodeFirst.InitTables(typeof(Student)); // 初始化表 - 没有则创建表
                    db.Deleteable<Student>().ExecuteCommand(); // 删除所有数据
                    List<Student> addlist = new List<Student>();
                    for (int i = 0; i < 100; i++)
                    {
                        addlist.Add(new Student()
                        {
                            Name = $"Name_{i}",
                            SchoolId = i,
                            CreateTime = DateTime.Now
                        });
                    }
                    //(1)、非参数化插入（防注入） 
                    //优点：综合性能比较平均，列少1万条也不慢，属于万写法,不加事务情况下部分库有失败回滚机质
                    //缺点：数据量超过5万以上占用内存会比较大些，内存小可以用下面2种方式处理
                    db.Insertable(addlist) // 创建插入对象 - 常用的插入方法
                        .ExecuteCommand(); // 执行插入命令
                }
                #endregion

                //分组聚合
                {
                    var list = db.Queryable<Student>() // 查询Student表中的数据
                             .GroupBy(it => new { it.Id, it.Name }) // 按Id和Name分组
                             .Having(it => SqlFunc.AggregateAvg(it.Id) > 0) // Having子句，筛选平均Id大于0的分组
                             .Select(it => new // 匿名类型
                             {
                                 idAvg = SqlFunc.AggregateAvg(it.Id),
                                 count = SqlFunc.AggregateCount(it.Id),
                                 name = it.Name
                             }) // 选择需要的字段
                             .ToList(); // 返回一个匿名类型的列表
                }

                //一般用来指定字段去重复,查询不重复的值,去重字段
                {
                    var list = db.Queryable<Student>() // 查询Student表中的数据
                        .Distinct() // 去重
                        .Select(it => new { it.Name }) // 选择Name列
                        .ToList();// 返回一个匿名类型的列表
                }

                //开窗函数 - 感觉有点像分组查询
                {
                    // 根据Name分组，获取分组后的第一条记录
                    var model = db.Queryable<Student>() // 查询Student表中的数据
                        .Take(1)// 取前1条记录 - 
                        .PartitionBy(it => it.Name)// 按Name分区 -
                        .ToList();// 返回一个Student类型的列表
                         // SELECT * FROM (
                         // SELECT[Id],[SchoolId],[StudentName],[CreateTime],ROW_NUMBER() OVER(PARTITION BY[StudentName] ORDER BY GetDate()) AS RowIndex  FROM[dbstudent]
                         //) T WHERE RowIndex BETWEEN 1 AND 1

                    var model1 = db.Queryable<Student>() // 查询Student表中的数据
                        .OrderBy(it => it.Id, OrderByType.Desc) // 按Id降序排序
                        .Take(1) // 取前1条记录
                        .PartitionBy(it => it.Name) // 按Name分区
                        .ToList(); // 返回一个Student类型的列表
                        // SELECT * FROM (
                        // SELECT[Id],[SchoolId],[StudentName],[CreateTime],ROW_NUMBER() OVER(PARTITION BY[StudentName] ORDER BY GetDate()) AS RowIndex  FROM[dbstudent]
                        //) T WHERE RowIndex BETWEEN 1 AND 1
                }

                //合并结合
                {
                    // 将子查询合成一个表 - 类似于临时表 - 然后可以在外层查询
                    var test48 = db.Queryable<Student>() // 查询Student表中的数据
                        .Select(it => new // 匿名类型
                        {
                            index2 = SqlFunc.RowNumber(it.Id, it.Name),// RowNumber函数获取行号
                            name = it.Name,
                            date = it.CreateTime
                        }) // 选择需要的字段
                    .MergeTable()// 将查询结果集变成表 - 将结果合并成一个表
                    .Where(it => it.index2 == 1) // 条件查询，行号等于1
                   .ToList(); // 返回一个匿名类型的列表
                    //SELECT* FROM(
                    //SELECT row_number() over(partition by [StudentName] order by[Id]) AS[index2] , [StudentName] AS[name] , [CreateTime] AS[date]  FROM[dbstudent]
                    //) MergeTable WHERE([index2] = 1)
                }

                //分页查询
                {
                    {
                        int pagenumber = 2; // 当前第几页 - pagenumber是从1开始的不是从零开始的
                        int pageSize = 20; // 每页页数
                        int totalCount = 0; // 总条数
                        //单表分页
                        var page = db.Queryable<Student>() // 查询Student表中的数据
                            .ToPageList(pagenumber, pageSize, ref totalCount); // ToPageList方法进行分页查询

                        // 新版本的数据库可以使用这种方式-效率更高一些
                        var page1 = db.Queryable<Student>() // 查询Student表中的数据
                          .ToOffsetPage(pagenumber, pageSize, ref totalCount); // ToOffsetPage方法进行分页查询

                    }
                    //如果SqlServer不想有Rownumber可以用 ToOffsetPage 较新版本支持 
                    //多表分页
                    {
                        int pagenumber = 1; // pagenumber是从1开始的不是从零开始的
                        int pageSize = 20; // 每页页数
                        int totalCount = 0; // 总条数
                        var list = db.Queryable<Company>() // 查询Company表中的数据
                       .LeftJoin<User>((c, u) => c.Id == u.CompanyId) // 左连接User表，连接条件为Company的Id等于User的CompanyId
                       .Select((c, u) => new // 匿名类型
                       {
                           Id = c.Id,
                           cName = c.CompanyName,
                           uId = u.Id,
                           uName = u.UserName
                       }) // 选择需要的字段
                       .ToOffsetPage(pagenumber, pageSize, ref totalCount); // ToOffsetPage方法进行分页查询
                    }

                    //异步分页
                    {
                        int pagenumber = 1; // pagenumber是从1开始的不是从零开始的
                        int pageSize = 20; // 每页页数
                        int totalCount = 0; // 总条数
                        RefAsync<int> total = 0;//REF和OUT不支持异步,想要真的异步这是最优解
                        Task<List<Student>> studentTask =
                            db.Queryable<Student>() // 查询Student表中的数据
                            .ToPageListAsync(pagenumber, pageSize, total);// ToPageListAsync方法进行异步分页查询
                        List<Student> list = studentTask.Result; // 获取异步查询结果

                    }
                }

                //Order排序
                {
                    var list = db.Queryable<Company, User>((c, u) => new JoinQueryInfos(JoinType.Left, c.Id == u.CompanyId)) // 查询Company和User表中的数据
                     .OrderBy(c => c.Id)//升序
                     .OrderBy((c, u) => c.CompanyName, OrderByType.Desc)//倒序 
                     .Select((c, u) => new // 匿名类型
                     {
                         cId = c.Id,
                         cName = c.CompanyName,
                         uId = u.Id,
                         uName = u.UserName
                     }) // 选择需要的字段
                     .ToList(); // 返回一个匿名类型的列表
                }
                //多个Order一起
                {
                    var list = db.Queryable<User>() // 查询User表中的数据
                        .OrderBy(it => new 
                        {
                            it.Id,
                            name = SqlFunc.Desc(it.UserName) // 使用SqlFunc.Desc进行降序排序
                        }) // 按Id升序，UserName降序排序
                        .ToList(); // 返回一个User类型的列表
                }

                //动态排序
                {
                    //通过类中属性名获取数据库字段名
                    {
                        var orderByFieldName = db.EntityMaintenance.GetDbColumnName<User>("Id");//防注入 - 作用不大
                        var list = db.Queryable<Student>() // 查询Student表中的数据
                            .OrderBy(orderByFieldName + " asc ") // 动态排序，按Id升序
                            .ToList();// 返回一个Student类型的列表
                    }

                    {
                        var list = db.Queryable<Company, User>((c, u) => new JoinQueryInfos(JoinType.Left, c.Id == u.CompanyId))// 查询Company和User表中的数据
                                     .OrderBy("c.id asc,u.Id desc ")  //多表查询有别名(c&u) 
                                       .Select((c, u) => new
                                       {
                                           cId = c.Id,
                                           cName = c.CompanyName,
                                           uId = u.Id,
                                           uName = u.UserName
                                       }) // 选择需要的字段
                                       .ToList(); // 返回一个匿名类型的列表
                    }

                    {
                        var pageJoin = db.Queryable<Company, User>((c, u) => new JoinQueryInfos(JoinType.Left, c.Id == u.CompanyId))
                                         .Select((c, u) => new
                                         {
                                             cId = c.Id,
                                             cName = c.CompanyName,
                                             uId = u.Id,
                                             uName = u.UserName
                                         })// 选择需要的字段
                                         .MergeTable()//将查询结果集变成表MergeTable
                                        .Where(it => it.cId == 1)// 条件查询，Company的Id等于1
                                        .OrderBy("cName asc")// 动态排序，按cName升序
                                        .ToList();//对表MergeTable进行排序
                    }

                    //随机排序取10条
                    {
                        db.Queryable<Student>() // 查询Student表中的数据
                            .Take(10)// 取前10条记录
                            .OrderBy(st => SqlFunc.GetRandom())// 随机排序
                            .ToList();// 返回一个Student类型的列表
                    }
                }
            }
        }
        #endregion

        #region 导航属性 一对一、一对多、多对一、多对多-多层级的数据操作
        /// <summary>
        /// 导航属性 一对一、一对多、多对一、多对多-多层级的数据操作
        /// </summary>
        public static void NavigationPropertiesShow()
        {
            ConnectionConfig connectionConfig = new ConnectionConfig()
            {
                ConnectionString = CustomConnectionConfig.ConnectionString001,// 数据库连接字符串
                IsAutoCloseConnection = true,// 自动关闭连接
                DbType = DbType.SqlServer// 数据库类型
            };
            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))// 创建SqlSugarClient实例
            {
                {
                    db.Aop.OnLogExecuting = (s, p) =>// 在执行SQL语句时触发
                    {
                        Console.WriteLine("----------------------------");
                        Console.WriteLine($"Sql语句:{s}");
                    };
                }
                #region 一对一关系 
                {
                    if (db.DbMaintenance.IsAnyTable("User", false))// 检查User表是否存在
                    {
                        db.DbMaintenance.DropTable<User>();// 如果存在则删除User表
                    }
                    if (db.DbMaintenance.IsAnyTable("UserDetail", false))// 检查UserDetail表是否存在
                    {
                        db.DbMaintenance.DropTable<UserDetail>();// 如果存在则删除UserDetail表
                    }

                    db.CodeFirst.InitTables<User>();// 初始化User表
                    db.CodeFirst.InitTables<UserDetail>();// 初始化UserDetail表

                    db.DeleteNav<User>(c => c.Id > 0)// 导航删除User表中Id大于0的记录
                        .Include(c => c.UserDetailInfo)// 包含UserDetailInfo导航属性
                        .ExecuteCommand();// 执行删除命令

                    #region 初始化数据
                    List<User> users = new List<User>()
                    {
                         new User()
                         {
                             CompanyId = 1,
                             UserName = "Richard",
                             CreateTime = DateTime.Now,
                             UserDetailInfo = new UserDetail()// 导航属性UserDetailInfo
                             {
                                 Address = "湖北武汉",
                                 Description = ".NET金牌讲师"
                             }
                         },
                         new User()
                         {
                             CompanyId = 1,
                             UserName = "cole老师号",
                             CreateTime = DateTime.Now,
                             UserDetailInfo = new UserDetail()// 导航属性UserDetailInfo
                             {
                                 Address = "湖北黄冈",
                                 Description = "金牌助教"
                             }
                         }
                    };
                    #endregion

                    //导航属性新增
                    bool bResult = db.InsertNav(users)// 插入导航属性数据
                           .Include(z1 => z1.UserDetailInfo)// 包含UserDetailInfo导航属性
                           .ExecuteCommand();// 执行插入命令

                    //导航属性查询 
                    var list1 = db.Queryable<User>()// 查询User表中的数据
                        .Includes(t => t.UserDetailInfo) //多层级 
                        .ToList();// 返回一个User类型的列表

                    var list2 = db.Queryable<User>()// 查询User表中的数据
                            .Includes(t => t.UserDetailInfo) //多层级 
                            .Where(c => c.UserName == "Richard")// 条件查询，UserName等于"Richard"
                            .ToList();// 返回一个User类型的列表

                    list2[0].UserName = "Richard老师";
                    list2[0].UserDetailInfo.Address = "湖北武汉汉阳";

                    bool bResult1 = db.UpdateNav(list2)// 更新导航属性数据
                       .Include(u => u.UserDetailInfo)// 包含UserDetailInfo导航属性
                       .ExecuteCommand();// 执行更新命令

                    bool bResult2 = db.DeleteNav<User>(list2)// 删除导航属性数据
                        .Include(c => c.UserDetailInfo)// 包含UserDetailInfo导航属性
                        .ExecuteCommand();// 执行删除命令
                }
                #endregion

                #region 一对多关系 与 多对一关系
                {
                    if (db.DbMaintenance.IsAnyTable("User", false))// 检查User表是否存在
                    {
                        db.DbMaintenance.DropTable<User>();// 如果存在则删除User表
                    }
                    if (db.DbMaintenance.IsAnyTable("Company", false))// 检查Company表是否存在
                    {
                        db.DbMaintenance.DropTable<Company>();// 如果存在则删除Company表
                    }
                    db.CodeFirst.InitTables<Company>();// 初始化Company表
                    db.CodeFirst.InitTables<User>();// 初始化User表

                    //导航删除
                    db.DeleteNav<Company>(c => c.Id > 0)// 删除Company表中Id大于0的记录
                       .Include(c => c.UserList)// 包含UserList导航属性
                       .ExecuteCommand();// 执行删除命令

                    #region 初始化数据
                    List<Company> companies = new List<Company>()
                    {
                        new Company()
                        {
                             CompanyName="朝夕教育",
                             CreateTime= DateTime.Now,
                             UserList=new List<User>(){ // 导航属性UserList
                                  new User()
                                  {
                                      CompanyId=1,
                                      CreateTime= DateTime.Now,
                                      UserName="Eleven"
                                  },
                                  new User()
                                  {
                                      CompanyId=1,
                                      CreateTime= DateTime.Now,
                                      UserName="Richard",
                                       UserDetailInfo=new UserDetail
                                       {
                                            Address="湖北武汉汉阳",
                                            Description="金牌讲师"
                                       }
                                  },
                                  new User()
                                  {
                                      CompanyId=1,
                                      CreateTime= DateTime.Now,
                                      UserName="Gerry"
                                  }
                                }// 导航属性UserList结束
                        },
                        new Company()
                        {
                            CompanyName="腾讯课堂",
                            CreateTime= DateTime.Now,
                        }
                    };
                    #endregion

                    //导航新增
                    db.InsertNav(companies)// 插入导航属性数据
                      .Include(c => c.UserList)// 包含UserList导航属性
                      .ExecuteCommand();// 执行插入命令

                    //一对多导航查询
                    var list = db.Queryable<Company>()// 查询Company表中的数据
                             .Includes(t => t.UserList)// 包含UserList导航属性
                             .ToList();// 返回一个Company类型的列表

                    #region 多对一导航查询
                    var userlist = db.Queryable<User>()// 查询User表中的数据
                            .Includes(u => u.CompanyInfo)// 包含CompanyInfo导航属性
                            .ToList();// 返回一个User类型的列表
                    #endregion

                    var list1 = db.Queryable<Company>()// 查询Company表中的数据
                      .Includes(x => x.UserList.Where(u => u.UserName == "Richard").ToList())// 包含UserList导航属性，并筛选UserName等于"Richard"
                      .Where(x => x.CompanyName.Contains("朝夕教育"))// 条件查询，CompanyName包含"朝夕教育"
                      .ToList();// 返回一个Company类型的列表
                    list1[0].CompanyName = "朝夕教育-金牌机构";
                    list1[0].UserList[0].UserName = "Richard老师";

                    //修改
                    bool bResult2 = db.UpdateNav(list1)// 更新导航属性数据
                    .Include(u => u.UserList)// 包含UserList导航属性
                    .ExecuteCommand();// 执行更新命令

                    ///删除
                    bool bResult3 = db.DeleteNav(list1)// 删除导航属性数据
                          .Include(u => u.UserList)// 包含UserList导航属性
                          .ExecuteCommand();// 执行删除命令
                }
                #endregion

                #region 多对多关系 
                {
                    if (db.DbMaintenance.IsAnyTable("User", false))// 检查User表是否存在
                    {
                        db.DbMaintenance.DropTable<User>();// 如果存在则删除User表
                    }
                    if (db.DbMaintenance.IsAnyTable("Role", false))// 检查Role表是否存在
                    {
                        db.DbMaintenance.DropTable<Role>();// 如果存在则删除Role表
                    }
                    if (db.DbMaintenance.IsAnyTable("UserRoleMapping", false))// 检查UserRoleMapping表是否存在
                    {
                        db.DbMaintenance.DropTable<UserRoleMapping>();// 如果存在则删除UserRoleMapping表
                    }
                    db.CodeFirst.InitTables<User>();// 初始化User表 没有则创建表
                    db.CodeFirst.InitTables<Role>();// 初始化Role表 没有则创建表
                    db.CodeFirst.InitTables<UserRoleMapping>(); // 初始化UserRoleMapping表 没有则创建表

                    #region 初始化数据
                    List<User> users = new List<User>()
                    {
                        new User()
                        {
                             CompanyId=1,
                             CreateTime= DateTime.Now,
                             UserName="Richard老师",
                             RoleList=new List<Role>()// 导航属性RoleList
                             {
                                 new Role()
                                 {
                                      CreateTime= DateTime.Now,
                                      RoleName="管理员"
                                 },
                                  new Role()
                                  {
                                        CreateTime= DateTime.Now,
                                        RoleName="金牌讲师"
                                  }
                             }
                        }
                    };
                    #endregion

                    db.InsertNav(users)// 插入导航属性数据
                       .Include(u => u.RoleList)// 插入第一层 SchoolA 
                       .ExecuteCommand();// 执行插入命令

                    var list1 = db.Queryable<User>()// 查询User表中的数据
                        .Includes(x => x.RoleList)// 包含RoleList导航属性
                        .ToList();// 返回一个User类型的列表

                    var list2 = db.Queryable<User>()// 查询User表中的数据
                        .Includes(x => x.RoleList.Where(r => r.RoleName == "管理员")// 角色表中-筛选RoleName等于"管理员"
                        .ToList())// 包含RoleList导航属性
                        .Where(c => c.UserName.Equals("Richard老师"))// 条件查询，UserName等于"Richard老师"
                        .ToList();// 返回一个User类型的列表

                    bool bResult = db.UpdateNav(list2)// 更新导航属性数据
                                  .Include(u => u.RoleList)// 包含RoleList导航属性
                                  .ExecuteCommand();// 执行更新命令

                    // 这里导航属性只能删除关系映射表中的数据，不能删除User和Role表中的数据
                    bool bResult1 = db.DeleteNav(list1)// 删除导航属性数据
                                 .Include(u => u.RoleList)// 包含RoleList导航属性
                                 .ExecuteCommand();// 执行删除命令


                    int iResult1 = db.Deleteable(list1)// 删除User表中的数据
                        .ExecuteCommand();// 执行删除命令

                    var roles = db.Queryable<Role>()// 查询Role表中的数据
                       .ToList();// 返回一个Role类型的列表

                    int iResult2 = db.Deleteable(roles)// 删除Role表中的数据
                        .ExecuteCommand();// 执行删除命令

                }
                #endregion

                #region  动态导航关联字段-手动、指定字段、多字段
                {

                    if (db.DbMaintenance.IsAnyTable("StudentA", false))// 检查StudentA表是否存在
                    {
                        db.DbMaintenance.DropTable<StudentA>();// 如果存在则删除StudentA表
                    }
                    if (db.DbMaintenance.IsAnyTable("BookA", false))// 检查BookA表是否存在
                    {
                        db.DbMaintenance.DropTable<BookA>();// 如果存在则删除BookA表
                    }
                    db.CodeFirst.InitTables<StudentA>();// 初始化StudentA表 没有则创建表
                    db.CodeFirst.InitTables<BookA>();// 初始化BookA表 没有则创建表

                    #region 初始化数据
                    List<StudentA> studentAs = new List<StudentA>()
                    {
                        new StudentA()
                        {
                            StudentId= 1,
                            Name="张三同学",
                        }
                    };

                    List<BookA> bookAs = new List<BookA>()
                    {
                        new BookA()
                        {
                             studenId= 1,
                              Name="语文",
                        },
                        new BookA()
                        {
                                studenId= 1,
                              Name="数学",
                        }
                     };
                    #endregion

                    db.Insertable(studentAs)// 插入StudentA表中的数据
                        .ExecuteCommand();// 执行插入命令
                    db.Insertable(bookAs)// 插入BookA表中的数据
                        .ExecuteCommand();// 执行插入命令


                    var list = db.Queryable<StudentA>()// 查询StudentA表中的数据
                                 .Includes(it => it.Books
                                           .MappingField(z => z.studenId, () => it.StudentId)// 映射字段，将BookA的studenId映射到StudentA的StudentId
                                           .Where(z => z.BookId == 1)// 条件查询，BookA的BookId等于1
                                           .ToList()// 包含Books导航属性，并筛选BookId等于1
                    )
                .ToList();// 返回一个StudentA类型的列表
                }
                #endregion

                #region 性能优化，- 导航属性在大数据量查询时，采用分段查询提高查询性能
                {

                    if (db.DbMaintenance.IsAnyTable("User", false))// 检查User表是否存在
                    {
                        db.DbMaintenance.DropTable<User>();// 如果存在则删除User表
                    }
                    if (db.DbMaintenance.IsAnyTable("Company", false))
                    {
                        db.DbMaintenance.DropTable<Company>();// 如果存在则删除Company表
                    }
                    db.CodeFirst.InitTables<Company>();// 初始化Company表 没有则创建表
                    db.CodeFirst.InitTables<User>();// 初始化User表 没有则创建表

                    //导航删除
                    db.DeleteNav<Company>(c => c.Id > 0)// 删除Company表中Id大于0的记录
                       .Include(c => c.UserList)// 包含UserList导航属性
                       .ExecuteCommand();// 执行删除命令

                    #region 初始化数据
                    List<Company> companies = new List<Company>();
                    for (int i = 0; i < 5000; i++)
                    {
                        Company company = new Company()
                        {
                            CompanyName = $"朝夕教育_{i}",
                            CreateTime = DateTime.Now
                        };
                        List<User> userlist = new List<User>();
                        for (int j = 0; j < 10; j++)
                        {
                            User user = new User()
                            {
                                CompanyId = 1,
                                CreateTime = DateTime.Now,
                                UserName = $"学员_{j}"
                            };
                            userlist.Add(user);
                        }
                        company.UserList = userlist;
                        companies.Add(company);
                    }
                    #endregion

                    db.InsertNav<Company>(companies)// 插入导航属性数据
                      .Include(c => c.UserList)// 包含UserList导航属性
                      .ExecuteCommand();// 执行插入命令

                    Console.WriteLine("====================================================================");

                    List<Company> resultList = new List<Company>();
                    db.Queryable<Company>()// 查询Company表中的数据
                           .Includes(it => it.UserList)// 包含UserList导航属性
                           .ForEach(it => resultList.Add(it), 300); //分段查询-每次查询300条-提高查询性能
                }

                #endregion

                #region 数据映射
                {
                    ////AutoMapper 

                    List<Company> companies = db.Queryable<Company>()// 查询Company表中的数据
                            .Includes(it => it.UserList)// 包含UserList导航属性
                            .ToList(); //每次查询300条 
                    List<CompanyDto> dtoList = companies.Adapt<List<CompanyDto>>();// 使用Mapster进行数据映射，将Company类型转换为CompanyDto类型
                }
                #endregion

                #region 导航方法
                {
                    if (db.DbMaintenance.IsAnyTable("Company", false))
                    {
                        db.DbMaintenance.DropTable<Company>();// 如果存在则删除Company表
                    }

                    if (db.DbMaintenance.IsAnyTable("User", false))
                    {
                        db.DbMaintenance.DropTable<User>();// 如果存在则删除User表
                    }
                    if (db.DbMaintenance.IsAnyTable("UserDetail", false))
                    {
                        db.DbMaintenance.DropTable<UserDetail>();// 如果存在则删除UserDetail表
                    }
                    db.CodeFirst.InitTables<Company>();// 初始化Company表 没有则创建表
                    db.CodeFirst.InitTables<User>();// 初始化User表 没有则创建表
                    db.CodeFirst.InitTables<UserDetail>();// 初始化UserDetail表 没有则创建表

                    #region 初始化数据
                    List<Company> companies = new List<Company>()
                    {
                        new Company()
                        {
                             CompanyName="朝夕教育",
                             CreateTime= DateTime.Now,
                             UserList=new List<User>(){
                                  new User()
                                  {
                                      CompanyId=1,
                                      CreateTime= DateTime.Now,
                                      UserName="Eleven"
                                  },
                                  new User()
                                  {
                                      CompanyId=1,
                                      CreateTime= DateTime.Now,
                                      UserName="Richard",
                                      UserDetailInfo=new UserDetail
                                       {
                                            Address="湖北武汉汉阳",
                                            Description="金牌讲师"
                                       }
                                  },
                                  new User()
                                  {
                                      CompanyId=1,
                                      CreateTime= DateTime.Now,
                                      UserName="Gerry"
                                  }
                                }
                        },
                        new Company()
                        {
                            CompanyName="腾讯课堂",
                            CreateTime= DateTime.Now,
                        }
                    };
                    #endregion

                    //导航新增
                    db.InsertNav(companies)// 插入导航属性数据
                      .Include(c => c.UserList)// 包含UserList导航属性
                      .ThenInclude(u => u.UserDetailInfo)// 包含UserDetailInfo导航属性
                      .ExecuteCommand();// 执行插入命令

                    Console.WriteLine("================================");
                    // 使用 Any方法查询 Company 表中是否存在 UserList 导航属性 - 可以提高查询性能
                    List<Company> companyList1 = db.Queryable<Company>()// 查询Company表中的数据
                        .Where(it => it.UserList.Any())// 查询Company表中有UserList的记录
                        .ToList();// 返回一个Company类型的列表

                    // 使用 Any方法查询 Company 表中是否存在 UserList 导航属性 - 可以提高查询性能
                    List<Company> companyList2 = db.Queryable<Company>()// 查询Company表中的数据
                        .Where(it => it.UserList.Any(c => c.UserName.Equals("Richard")))// 查询Company表中有UserList且UserName等于"Richard"的记录
                        .ToList();// 返回一个Company类型的列表



                    if (db.DbMaintenance.IsAnyTable("User", false))
                    {
                        db.DbMaintenance.DropTable<User>();// 如果存在则删除User表
                    }
                    if (db.DbMaintenance.IsAnyTable("UserDetail", false))
                    {
                        db.DbMaintenance.DropTable<UserDetail>();// 如果存在则删除UserDetail表
                    }

                    db.CodeFirst.InitTables<User>();// 初始化User表 没有则创建表
                    db.CodeFirst.InitTables<UserDetail>();// 初始化UserDetail表 没有则创建表

                    db.DeleteNav<User>(c => c.Id > 0)// 删除User表中Id大于0的记录
                        .Include(c => c.UserDetailInfo)// 包含UserDetailInfo导航属性
                        .ExecuteCommand();// 执行删除命令

                    #region 初始化数据
                    List<User> users = new List<User>()
                    {
                         new User()
                         {
                             CompanyId = 1,
                             UserName = "Richard",
                             CreateTime = DateTime.Now,
                             UserDetailInfo = new UserDetail()
                             {
                                 Address = "湖北武汉",
                                 Description = ".NET金牌讲师"
                             }
                         },
                         new User()
                         {
                             CompanyId = 1,
                             UserName = "cole老师号",
                             CreateTime = DateTime.Now,
                             UserDetailInfo = new UserDetail()
                             {
                                 Address = "湖北黄冈",
                                 Description = "金牌助教"
                             }
                         }
                    };
                    #endregion

                    db.InsertNav(users)// 插入导航属性数据
                        .Include(c => c.CompanyInfo)// 包含CompanyInfo导航属性
                        .ExecuteCommand();// 执行插入命令

                    // 使用Exists方法查询 User 表中是否存在 UserDetailInfo 导航属性 - 可以提高查询性能
                    List<User> userlist = db.Queryable<User>()// 查询User表中的数据
                           .Where(x => SqlFunc.Exists(x.UserDetailInfo.Id))// 查询User表中存在UserDetailInfo的记录 - 
                           .ToList();// 返回一个User类型的列表


                }
                #endregion

                #region 联表导航 - 在没有导航属性的情况下实现导航属性效果
                {
                    Console.WriteLine("================联表导航=====================");

                    if (db.DbMaintenance.IsAnyTable("StudentA", false))// 检查StudentA表是否存在
                    {
                        db.DbMaintenance.DropTable<StudentA>();// 如果存在则删除StudentA表
                    }
                    if (db.DbMaintenance.IsAnyTable("RoomA", false))// 检查RoomA表是否存在
                    {
                        db.DbMaintenance.DropTable<RoomA>();// 如果存在则删除RoomA表
                    }
                    if (db.DbMaintenance.IsAnyTable("SchoolA", false))// 检查SchoolA表是否存在
                    {
                        db.DbMaintenance.DropTable<SchoolA>();// 如果存在则删除SchoolA表
                    }
                    if (db.DbMaintenance.IsAnyTable("TeacherA", false))// 检查TeacherA表是否存在
                    {
                        db.DbMaintenance.DropTable<TeacherA>();// 如果存在则删除TeacherA表
                    }

                    db.CodeFirst.InitTables<StudentA, RoomA, SchoolA, TeacherA>();// 初始化StudentA、RoomA、SchoolA、TeacherA表 没有则创建表
                    db.DbMaintenance.TruncateTable<StudentA>();// 清空StudentA表
                    db.DbMaintenance.TruncateTable<RoomA>();// 清空RoomA表
                    db.DbMaintenance.TruncateTable<SchoolA>();// 清空SchoolA表
                    db.DbMaintenance.TruncateTable<TeacherA>();// 清空TeacherA表
                    db.Insertable(new RoomA() { RoomId = 1, RoomName = "北大001室", SchoolId = 1 })// 插入RoomA表中的数据
                        .ExecuteCommand();
                    db.Insertable(new RoomA() { RoomId = 2, RoomName = "北大002室", SchoolId = 1 })// 插入RoomA表中的数据
                        .ExecuteCommand();
                    db.Insertable(new RoomA() { RoomId = 3, RoomName = "北大003室", SchoolId = 1 })// 插入RoomA表中的数据
                        .ExecuteCommand();
                    db.Insertable(new RoomA() { RoomId = 4, RoomName = "清华001厅", SchoolId = 2 })// 插入RoomA表中的数据
                        .ExecuteCommand();
                    db.Insertable(new RoomA() { RoomId = 5, RoomName = "清华002厅", SchoolId = 2 })// 插入RoomA表中的数据
                        .ExecuteCommand();
                    db.Insertable(new RoomA() { RoomId = 6, RoomName = "清华003厅", SchoolId = 2 })// 插入RoomA表中的数据
                        .ExecuteCommand();


                    db.Insertable(new SchoolA() { SchoolId = 1, SchoolName = "北大" })// 插入SchoolA表中的数据
                        .ExecuteCommand();
                    db.Insertable(new SchoolA() { SchoolId = 2, SchoolName = "清华" })// 插入SchoolA表中的数据
                        .ExecuteCommand();

                    db.Insertable(new StudentA() { StudentId = 1, SchoolId = 1, Name = "北大jack" })
                        .ExecuteCommand();
                    db.Insertable(new StudentA() { StudentId = 2, SchoolId = 1, Name = "北大tom" })
                        .ExecuteCommand();
                    db.Insertable(new StudentA() { StudentId = 3, SchoolId = 2, Name = "清华jack" })
                        .ExecuteCommand();
                    db.Insertable(new StudentA() { StudentId = 4, SchoolId = 2, Name = "清华tom" })
                        .ExecuteCommand();

                    db.Insertable(new TeacherA() { SchoolId = 1, Id = 1, Name = "北大老师01" }).ExecuteCommand();
                    db.Insertable(new TeacherA() { SchoolId = 1, Id = 2, Name = "北大老师02" }).ExecuteCommand();

                    db.Insertable(new TeacherA() { SchoolId = 2, Id = 3, Name = "清华老师01" }).ExecuteCommand();
                    db.Insertable(new TeacherA() { SchoolId = 2, Id = 4, Name = "清华老师02" }).ExecuteCommand();

                    Console.WriteLine("=================================================");

                    var list = db.Queryable<StudentA>().ToList();//这儿也可以联表查询

                    //ThenMapper联表查询-将SchoolA表中的数据映射到StudentA中
                    db.ThenMapper(list, stu =>
                    {
                        //如果加Where不能带有stu参数，stu参数写到 SetContext
                        stu.SchoolA = db.Queryable<SchoolA>()// 查询SchoolA表中的数据
                        .SetContext(scl => scl.SchoolId, () => stu.SchoolId, stu)// 设置上下文，将SchoolA的SchoolId与StudentA的SchoolId进行关联
                        .FirstOrDefault();// 返回第一个匹配的SchoolA记录
                    });//联表查询-将SchoolA表中的数据映射到StudentA中
                }
                #endregion

                #region 实现无限层--树查询 - 这个有用
                {

                    if (db.DbMaintenance.IsAnyTable("Tree", false))// 检查Tree表是否存在
                    {
                        db.DbMaintenance.DropTable<Tree>();// 如果存在则删除Tree表
                    }
                    db.CodeFirst.InitTables<Tree>();// 初始化Tree表 没有则创建表

                    #region 初始化数据
                    Tree tree = new Tree()
                    {
                        Id = 1,
                        Name = "一级树",
                        ParentId = 0,
                        Child = new List<Tree>
                        {
                            new Tree()
                            {
                                ParentId=1,
                                Id = 5,
                                Name="二级目录-1",
                                Child=new List<Tree>
                                {
                                    new Tree() {
                                         Id = 6,
                                         Name="三级目录-1",
                                         ParentId=2,
                                         Child=new List<Tree>
                                         {
                                             new Tree() {
                                                 Id = 7,
                                                 ParentId=6,
                                                 Name="四级目录-1"
                                             }
                                         }
                                    }
                                }
                            }
                        }

                    };
                    #endregion

                    db.InsertNav<Tree>(tree)// 导航属性新增
                        .Include(it => it.Child)// 包含Child导航属性
                        .ThenInclude(c => c.Child)// 包含Child的Child导航属性
                        .ThenInclude(c1 => c1.Child)// 包含Child的Child的Child导航属性
                        .ThenInclude(c2 => c2.Child)// 包含Child的Child的Child的Child导航属性
                        .ExecuteCommand();// 执行插入命令

                    var treeRoot = db.Queryable<Tree>()//
                        .Where(it => it.Id == 1)// 查询Id为1的树节点
                        .ToList();// 返回一个Tree类型的列表
                    //第一层
                    db.ThenMapper(treeRoot, item =>
                    {
                        item.Child = db.Queryable<Tree>()// 查询Tree表中的数据
                        .SetContext(x => x.ParentId, () => item.Id, item)// 设置上下文，将Tree的ParentId与item的Id进行关联
                        .ToList();// 返回一个Tree类型的列表
                    });//联表查询-将Tree表中的数据映射到Tree中
                    //第二层
                    db.ThenMapper(treeRoot.SelectMany(it => it.Child), it =>
                    {
                        it.Child = db.Queryable<Tree>()// 查询Tree表中的数据
                        .SetContext(x => x.ParentId, () => it.Id, it)// 设置上下文，将Tree的ParentId与it的Id进行关联
                        .ToList();// 返回一个Tree类型的列表
                    });//联表查询-将Tree表中的数据映射到Tree中
                    //第三层
                    db.ThenMapper(treeRoot.SelectMany(it => it.Child).SelectMany(it => it.Child), it =>
                    {
                        it.Child = db.Queryable<Tree>()// 查询Tree表中的数据
                        .SetContext(x => x.ParentId, () => it.Id, it)// 设置上下文，将Tree的ParentId与it的Id进行关联
                        .ToList();// 返回一个Tree类型的列表
                    });

                    // 查询所有下级 - 还是这个方法好用
                    List<Tree> list = db.Queryable<Tree>()// 查询Tree表中的数据
                        .ToTree(it => it.Child, it => it.ParentId, 0);// 将Tree表中的数据转换为树形结构，Child为子节点，ParentId为父节点，0为根节点的ParentId
                }

                #endregion 
            }
        }
        #endregion

        #region 树查询+表达式目录树查询
        /// <summary>
        /// 树查询+表达式目录树查询
        /// </summary>
        public static void TreeAndExpressionQuery()
        {
            ConnectionConfig connectionConfig = new ConnectionConfig()
            {
                ConnectionString = CustomConnectionConfig.ConnectionString001,
                IsAutoCloseConnection = true,
                DbType = DbType.SqlServer
            };
            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                db.Aop.OnLogExecuting = (s, p) =>
                {
                    Console.WriteLine("----------------------------");
                    Console.WriteLine($"Sql语句:{s}");
                };

                if (db.DbMaintenance.IsAnyTable("Tree", false))
                {
                    db.DbMaintenance.DropTable<Tree>();
                }
                db.CodeFirst.InitTables<Tree>();


                #region 树递归查询
                {
                    //if (db.DbMaintenance.IsAnyTable("Tree", false))
                    //{
                    //    db.DbMaintenance.DropTable<Tree>();
                    //}
                    //db.CodeFirst.InitTables<Tree>();

                    //Tree tree = new Tree()
                    //{
                    //    Id = 1,
                    //    Name = "一级树",
                    //    ParentId = 0,
                    //    Child = new List<Tree>
                    //    {
                    //        new Tree()
                    //        {
                    //            ParentId=1,
                    //            Id = 5,
                    //            Name="二级目录-1",
                    //            Child=new List<Tree>
                    //            {
                    //                new Tree() {
                    //                     Id = 6,
                    //                     Name="三级目录-1",
                    //                     ParentId=2,
                    //                     Child=new List<Tree>
                    //                     {
                    //                         new Tree() {
                    //                             Id = 7,
                    //                             ParentId=6,
                    //                             Name="四级目录-1"
                    //                         }
                    //                     }
                    //                }
                    //            }
                    //        }
                    //    }

                    //};

                    //db.InsertNav<Tree>(tree)
                    //    .Include(it => it.Child)
                    //    .ThenInclude(c => c.Child)
                    //    .ThenInclude(c1 => c1.Child)
                    //    .ThenInclude(c2 => c2.Child)
                    //    .ExecuteCommand();

                    ////查询所有下级
                    ////从ParentId 为0 开始查询下级
                    //List<Tree> childlist = db.Queryable<Tree>().ToTree(it => it.Child, it => it.ParentId, 0);

                    ////查询所有上级
                    //List<Tree> parentlist = db.Queryable<Tree>().ToParentList(it => it.ParentId, 6);

                    ////条件查询，树形查询
                    //List<Tree> treelist = db.Queryable<Tree>().Where(it => it.ParentId > 5)
                    //    .ToTree(it => it.Child, it => it.ParentId, 0);



                    //if (db.DbMaintenance.IsAnyTable("Tree2", false))
                    //{
                    //    db.DbMaintenance.DropTable<Tree2>();
                    //}
                    //db.CodeFirst.InitTables<Tree2>();


                    //List<Tree2> tree2addlist = new List<Tree2>()
                    //{ 
                    //    new Tree2()
                    //    {

                    //        Name = "一级树",
                    //        ParentCode ="",
                    //        Code="001"
                    //    },
                    //    new Tree2()
                    //    {
                    //        ParentCode="001", 
                    //        Name="二级目录-1",
                    //        Code="002"
                    //    },
                    //    new Tree2() 
                    //    {

                    //        Name="三级目录-1",
                    //        ParentCode="002",
                    //        Code="003"
                    //    },
                    //    new Tree2() 
                    //    { 
                    //        ParentCode="003",
                    //        Name="四级目录-1",
                    //        Code="004"
                    //    }
                    //}; 
                    //db.Insertable<Tree2>(tree2addlist) 
                    //    .ExecuteCommand();


                    //List<Tree2> child21list = db.Queryable<Tree2>().ToTree(it => it.Child, it => it.ParentCode, "001");
                    //List<Tree2> child22list = db.Queryable<Tree2>().ToTree(it => it.Child, it => it.ParentCode, "002");

                    ////查询所有上级
                    //List<Tree2> parent2list = db.Queryable<Tree2>().ToParentList(it => it.Child, "004");

                    ////条件查询，树形查询
                    //List<Tree2> tree2list = db.Queryable<Tree2>().Where(it => it.Name.Contains("目录"))
                    //    .ToTree(it => it.Child, it => it.ParentCode, "001");

                }
                #endregion

                #region 表达式目录树
                {
                    //表达式目录树连写
                    {

                        Console.WriteLine("========================================================================");

                        string CompanyName = "";
                        int? id = 1;

                        //用例1:连写
                        Expression<Func<Company, bool>> exp = Expressionable.Create<Company>() //创建表达式
                        .AndIF(string.IsNullOrWhiteSpace(CompanyName) == false, it => it.CompanyName == CompanyName)//添加条件
                        .AndIF(id != null, it => it.Id == id)//添加条件
                        .ToExpression();//注意 这一句 不能少 
                        var list = db.Queryable<Company>()//
                            .Where(exp)// 表达式条件
                            .ToList();//直接用就行了不需要判段 null和加true
                    }

                    //表达式目录树分开写
                    {
                        Console.WriteLine("========================================================================");
                        string CompanyName = "朝夕教育";
                        int? id = 1;
                        Expressionable<Company> expable = Expressionable.Create<Company>(); // 创建表达式

                        if (string.IsNullOrWhiteSpace(CompanyName) == false)
                        {
                            expable.And(it => it.CompanyName == CompanyName); // 添加条件
                        }
                        if (id != null)
                        {
                            expable.And(it => it.CompanyName == CompanyName);// 添加条件
                        }
                        Expression<Func<Company, bool>> exp = expable.ToExpression();//要用变量 var exp=

                        db.Queryable<Company>().Where(exp).ToList();//直接用就行了不需要判段 null和加true
                    }


                    //拓展用例
                    {
                        Console.WriteLine("========================================================================");
                        var names = new string[] { "朝夕教育", "腾讯课堂" };
                        Expressionable<Company> exp = Expressionable.Create<Company>(); // 创建表达式
                        foreach (var item in names)
                        {
                            exp.Or(it => it.CompanyName.Contains(item.ToString()));// 添加或条件
                        }
                        var list = db.Queryable<Company>().Where(exp.ToExpression()).ToList();// 表达式查询
                    }

                    // Queyable.Or
                    {
                        Console.WriteLine("========================================================================");
                        var exp = Expressionable.Create<Company>() // 创建表达式
                             .And(it => it.Id == 1) // 添加并且条件
                             .Or(it => it.Id == 100)// 添加或条件
                             .ToExpression();//注意 这一句 不能少

                        var list = db.Queryable<Company>().Where(exp).ToList();// 表达式查询
                    }

                    #region 表达式目录树的解析代码实例
                    //解析表达式目录树 - 解析表达式实例
                    {
                        Console.WriteLine("========================================================================");
                        var expContext = new SqlServerExpressionContext();
                        Expression<Func<Company, bool>> exp = c => c.CompanyName.Contains("朝夕教育");

                        expContext.Resolve(exp, ResolveExpressType.WhereSingle);
                        var wheresql = expContext.Result.GetString();

                        var pars = expContext.Parameters;
                        db.Queryable<Company>().Where(wheresql).AddParameters(pars).ToList();
                    }

                    //匿名表达式解析
                    {
                        Console.WriteLine("========================================================================");
                        DbType dbtype = DbType.SqlServer;
                        ExpressionContext expContext = null;
                        switch (dbtype)
                        {
                            case DbType.MySql:
                                expContext = new MySqlExpressionContext();
                                break;
                            case DbType.SqlServer:
                                expContext = new SqlServerExpressionContext();
                                break;
                            case DbType.Sqlite:
                                expContext = new SqliteExpressionContext();
                                break;
                            case DbType.Oracle:
                                expContext = new OracleExpressionContext();
                                break;
                            case DbType.PostgreSQL:
                                expContext = new PostgreSQLExpressionContext();
                                break;
                            case DbType.Dm:
                                expContext = new DmExpressionContext();
                                break;
                            case DbType.Kdbndp:
                                expContext = new KdbndpExpressionContext();
                                break;
                            default:
                                throw new Exception("不支持");
                        }

                        Expression<Func<Company, bool>> exp = c => c.CompanyName.Contains("朝夕教育");

                        expContext.Resolve(exp, ResolveExpressType.WhereSingle);
                        var wheresql = expContext.Result.GetString();

                        var pars = expContext.Parameters;
                        db.Queryable<Company>().Where(wheresql).AddParameters(pars).ToList();

                    }

                    #region Where条件解析
                    {
                        Console.WriteLine("========================================================================");
                        var expContext = new SqlServerExpressionContext();
                        Expression<Func<Company, bool>> exp = it => it.CompanyName.Contains("朝夕教育");
                        expContext.Resolve(exp, ResolveExpressType.WhereSingle);
                        var value = expContext.Result.GetString();
                        var pars = expContext.Parameters;
                    }
                    #endregion

                    #region Where-Like解析
                    {
                        Console.WriteLine("========================================================================");
                        Expression<Func<Student, bool>> exp = it => it.Name.Contains("Richard老师");
                        ExpressionContext expContext = new ExpressionContext();
                        expContext.Resolve(exp, ResolveExpressType.WhereMultiple);
                        var value = expContext.Result.GetString();
                        var pars = expContext.Parameters;
                    }
                    #endregion

                    #region Select的解析 
                    {
                        Console.WriteLine("========================================================================");
                        Expression<Func<Company, CompanyDto>> exp = it => new CompanyDto()
                        {
                            CompanyName = it.CompanyName,
                            CreateTime = it.CreateTime,
                        };
                        ExpressionContext expContext = new ExpressionContext();
                        expContext.IsSingle = false;
                        expContext.Resolve(exp, ResolveExpressType.SelectSingle);
                        var selectorValue = expContext.Result.GetString();
                        var pars = expContext.Parameters;
                    }
                    #endregion
                    #endregion
                }
                #endregion 

            }
        }
        #endregion

        #region 跨库查询
        /// <summary>
        ///  跨库查询
        /// </summary>
        public static void CrossDatabaseQuery()
        {

            #region 跨库查询
            {
                // 配置多个数据库连接-用于实现跨库查询
                List<ConnectionConfig> connetctionlist = new List<ConnectionConfig>()
                {
                  new ConnectionConfig()
                  {
                     ConfigId="db1",
                      DbType=DbType.SqlServer,
                     ConnectionString=CustomConnectionConfig.ConnectionString001,
                     IsAutoCloseConnection=true
                  },
                  new ConnectionConfig()
                  {
                     ConfigId="db2",
                      DbType=DbType.SqlServer,
                     ConnectionString=CustomConnectionConfig.ConnectionString003,
                     IsAutoCloseConnection=true
                  }
                };
                using (SqlSugarClient db = new SqlSugarClient(connetctionlist))
                {

                    {
                        db.Aop.OnLogExecuting = (s, p) =>
                        {
                            Console.WriteLine("----------------------------");
                            Console.WriteLine($"Sql语句:{s}");
                        };
                    }

                    db.GetConnection("db1").DbMaintenance.CreateDatabase();
                    db.GetConnection("db2").DbMaintenance.CreateDatabase();
                    if (db.GetConnection("db1").DbMaintenance.IsAnyTable("OrderHead", false))
                    {

                        db.GetConnection("db1").DbMaintenance.DropTable<OrderHead>();
                    }
                    if (db.GetConnection("db2").DbMaintenance.IsAnyTable("OrderItem", false))
                    {
                        db.GetConnection("db2").DbMaintenance.DropTable<OrderItem>();
                    }
                    db.GetConnection("db1").CodeFirst.InitTables<OrderHead>();
                    db.GetConnection("db2").CodeFirst.InitTables<OrderItem>();


                    List<OrderHead> orders = new List<OrderHead>()
                    {
                        new OrderHead(){
                              Id= 1,
                              Name="自行车订单",
                              Price=3000,
                              CreateTime=DateTime.Now,
                               CountInfo=1,
                        }
                    };
                    List<OrderItem> itemsList = new List<OrderItem>()
                    {
                       new OrderItem()
                       {
                          CreateTime=DateTime.Now,
                          Price=2900,
                          ItemId=1,
                          OrderId=1,
                       },
                       new OrderItem()
                       {
                          CreateTime=DateTime.Now,
                          Price=100,
                          ItemId=2,
                          OrderId=1,
                       }
                    };

                    db.GetConnection("db1").Insertable(orders)
                        .ExecuteCommand();

                    db.GetConnection("db2").Insertable(itemsList)
                       .ExecuteCommand();




                    //通过实体类特性Tenant自动映射不同数据库进行查询
                    {
                        var list = db.QueryableWithAttr<OrderItem>() // 实现跨库查询操作
                                   .Includes(z => z.Order)
                                   .ToList(); //1行代码就搞定了2个库联表查询

                        var list1 = db.QueryableWithAttr<OrderHead>() // 实现跨库查询操作
                                    .Includes(z => z.Items)
                                    .ToList(); //1行代码就搞定了2个库联表查询
                    }

                    //不通过特性实现跨库导航
                    {
                        // 需要指定跨库的ConfigId - 就可以跨库查询
                        var list = db.GetConnection("db2") // 指定数据库连接
                            .Queryable<OrderItem>()//Orderitem是db2
                                  .CrossQuery(typeof(OrderHead), "db1")//Order是db1 指定OrderHead表是数据库db1的
                                  .Includes(z => z.Order) // 多层级 包含Order导航属性
                                  .ToList();
                        // 需要指定跨库的ConfigId - 就可以跨库查询
                        var list1 = db.GetConnection("db1").Queryable<OrderHead>()//Orderitem是db2
                                 .CrossQuery(typeof(OrderItem), "db2")//Order是db1
                                 .Includes(z => z.Items)// 
                                 .ToList();
                    }

                    {
                        var list = db.Queryable<OrderHead>() // 查询OrderHead表中数据
                            .AS("ZhaoxiSqlSugarDb.dbo.OrderHead") // 指定要查询的数据库表
                            .ToList();

                        //多表跨库
                        var list1 = db.Queryable<OrderHead>() // 查询OrderHead表中数据
                            .AS("ZhaoxiSqlSugarDb.dbo.OrderHead") // 指定要查询的数据库表
                                .LeftJoin<OrderItem>((o, i) => o.Id == i.OrderId)// 左连接
                                .AS<OrderItem>("ZhaoxiSqlSugarDb_Item.dbo.OrderItem") //AS<T>  指定要查询的数据库表
                                .ToList();
                    }

                }





            }
            #endregion
        }
        #endregion

        #region 报表查询 - 提供的统计报表月份有限 - 作用不大
        /// <summary>
        /// 报表查询 - 提供的统计报表月份有限 - 作用不大
        /// </summary>
        public static void ReportQuery()
        {
            var connetction = new ConnectionConfig()
            {
                DbType = DbType.SqlServer,
                ConnectionString = CustomConnectionConfig.ConnectionString001,
                IsAutoCloseConnection = true
            };
            using (SqlSugarClient db = new SqlSugarClient(connetction))
            {
                #region 初始化表结构和数据 - 初始化40年的报表数据
                {
                    // 记录查询sql语句
                    db.Aop.OnLogExecuting = (s, p) => 
                    {
                        Console.WriteLine("----------------------------");
                        Console.WriteLine($"Sql语句:{s}");
                    };

                    if (db.DbMaintenance.IsAnyTable("Operateinfo", false))
                    {
                        db.DbMaintenance.DropTable<Operateinfo>(); // 删除表
                    }
                    db.CodeFirst.InitTables<Operateinfo>(); // 创建表

                    List<Operateinfo> list = new List<Operateinfo>();
                    for (int i = 0; i < 100000; i++)
                    {
                        list.Add(new Operateinfo()
                        {
                            // 这个随机生成时间的方法挺好的
                            Operate_time = DateTime.Now.AddMonths(new Random().Next(-6, 6)).AddYears(new Random().Next(-20, 20)), 
                            Operate_Type = i,
                            Userid = i,
                        });
                    }
                    db.Fastest<Operateinfo>()//创建快速插入对象 - 适合大数据量插入
                        .BulkCopy(list); // 执行批量插入命令 - 适合大数据量插入
                }
                #endregion

                //统计当前年份
                {
                    Console.WriteLine("统计当前年份");
                    var queryableLeft = db.Reportable(ReportableDateType.MonthsInLast1years) // 统计报表
                        .ToQueryable<DateTime>(); // 根据时间统计
                    var queryableRight = db.Queryable<Operateinfo>();// 查询Operateinfo表中数据

                    var resultlistx = db.Queryable(queryableLeft)
                        .ToList();

                    var resultlist = db.Queryable(queryableLeft, queryableRight, JoinType.Left, (x1, x2) => x2.Operate_time.ToString("yyyy-MM") == x1.ColumnName.ToString("yyyy-MM"))
                     .GroupBy((x1, x2) => x1.ColumnName) 
                     .Select((x1, x2) => new
                     {
                         count = SqlFunc.AggregateSum(SqlFunc.IIF(x2.Id > 0, 1, 0)), //null的数据要为0所以不能用count
                         date = x1.ColumnName.ToString("yyyy-MM")
                     }).ToList()
                     .OrderBy(c => c.date)
                     .ToList();

                    var queryableLeft1 = resultlist.Sum(c => c.count);
                    int lastYearcoutn = db.Queryable<Operateinfo>().Count(c => c.Operate_time.Year == 2022);
                }

                {
                    //统计最近三年
                    Console.WriteLine("统计最近三年");
                    var queryableLeft = db.Reportable(ReportableDateType.MonthsInLast3years)
                        .ToQueryable<DateTime>(); // 根据时间统计
                    var queryableRight = db.Queryable<Operateinfo>();

                    var resultlist = db.Queryable(queryableLeft, queryableRight, JoinType.Left, (x1, x2) => x2.Operate_time.ToString("yyyy-MM") == x1.ColumnName.ToString("yyyy-MM"))
                    .GroupBy((x1, x2) => x1.ColumnName)
                    .Select((x1, x2) => new
                    {
                        count = SqlFunc.AggregateSum(SqlFunc.IIF(x2.Id > 0, 1, 0)), //null的数据要为0所以不能用count
                        date = x1.ColumnName.ToString("yyyy-MM")
                    }
                    ).ToList().OrderBy(c => c.date)
                    .ToList();

                    var threeYearCount = resultlist.Sum(c => c.count);
                    int threeYearCount1 = db.Queryable<Operateinfo>().Count(c => c.Operate_time.Year == 2022 || c.Operate_time.Year == 2021 || c.Operate_time.Year == 2020);

                }

                {
                    //统计最近10年;
                    Console.WriteLine("最近10年");
                    var queryableLeft = db.Reportable(ReportableDateType.MonthsInLast10years)// 统计报表
                        .ToQueryable<DateTime>(); // 根据时间统计

                    var queryableRight = db.Queryable<Operateinfo>();

                    var resultlist = db.Queryable(queryableLeft, queryableRight, JoinType.Left, (x1, x2) => x2.Operate_time.ToString("yyyy-MM") == x1.ColumnName.ToString("yyyy-MM"))
                    .GroupBy((x1, x2) => x1.ColumnName)
                    .Select((x1, x2) => new
                    {
                        count = SqlFunc.AggregateSum(SqlFunc.IIF(x2.Id > 0, 1, 0)), //null的数据要为0所以不能用count
                        date = x1.ColumnName.ToString("yyyy-MM")
                    }
                    ).ToList().OrderBy(c => c.date)
                    .ToList();
                    var tenYearCount = resultlist.Sum(c => c.count);

                    int tenYearCount1 = db.Queryable<Operateinfo>().Count(c => c.Operate_time.Year == 2022
                        || c.Operate_time.Year == 2021
                        || c.Operate_time.Year == 2020
                        || c.Operate_time.Year == 2019
                        || c.Operate_time.Year == 2018
                        || c.Operate_time.Year == 2017
                        || c.Operate_time.Year == 2016
                        || c.Operate_time.Year == 2015
                        || c.Operate_time.Year == 2014
                        || c.Operate_time.Year == 2013);
                }

                {

                    //统计今年一月份统计 
                    Console.WriteLine("统计今年一月份统计 ");
                    var queryableLeft = db.Reportable(ReportableDateType.years1)// 统计报表
                        .ToQueryable<DateTime>();//根据时间统计

                    var queryableRight = db.Queryable<Operateinfo>();

                    var resultlist = db.Queryable(queryableLeft, queryableRight, JoinType.Left, (x1, x2) => x2.Operate_time.ToString("yyyy-MM") == x1.ColumnName.ToString("yyyy-MM"))
                    .GroupBy((x1, x2) => x1.ColumnName)
                    .Select((x1, x2) => new
                    {
                        count = SqlFunc.AggregateSum(SqlFunc.IIF(x2.Id > 0, 1, 0)), //null的数据要为0所以不能用count
                        date = x1.ColumnName.ToString("yyyy-MM")
                    }
                    ).ToList().OrderBy(c => c.date)
                    .ToList();

                    var years1Count1 = resultlist.Sum(c => c.count);
                    int years1Count2 = db.Queryable<Operateinfo>().Count(c => c.Operate_time.Year == 2022 && c.Operate_time.Month == 1);

                }

                {
                    //最近三年一月份统计 
                    Console.WriteLine("最近三年一月份统计  ");
                    var queryableLeft = db.Reportable(ReportableDateType.years3)// 统计报表
                        .ToQueryable<DateTime>();// 根据时间统计
                    var queryableRight = db.Queryable<Operateinfo>();
                    var resultlist = db.Queryable(queryableLeft, queryableRight, JoinType.Left, (x1, x2) => x2.Operate_time.ToString("yyyy-MM") == x1.ColumnName.ToString("yyyy-MM"))
                    .GroupBy((x1, x2) => x1.ColumnName)
                    .Select((x1, x2) => new
                    {
                        count = SqlFunc.AggregateSum(SqlFunc.IIF(x2.Id > 0, 1, 0)), //null的数据要为0所以不能用count
                        date = x1.ColumnName.ToString("yyyy-MM")
                    }
                    ).ToList().OrderBy(c => c.date)
                    .ToList();

                    var years1Count = resultlist.Sum(c => c.count);
                    int years1Count1 = db.Queryable<Operateinfo>().Count(c => (c.Operate_time.Year == 2022 && c.Operate_time.Month == 1) || (c.Operate_time.Year == 2021 && c.Operate_time.Month == 1)
                  || (c.Operate_time.Year == 2020 && c.Operate_time.Month == 1));
                }

                {
                    //最近10年一月份统计 
                    Console.WriteLine("最近10年一月份统计 ");
                    var queryableLeft = db.Reportable(ReportableDateType.years10)
                        .ToQueryable<DateTime>();
                    var queryableRight = db.Queryable<Operateinfo>();
                    var resultlist = db.Queryable(queryableLeft, queryableRight, JoinType.Left, (x1, x2) => x2.Operate_time.ToString("yyyy-MM") == x1.ColumnName.ToString("yyyy-MM"))
                    .GroupBy((x1, x2) => x1.ColumnName)
                    .Select((x1, x2) => new
                    {
                        count = SqlFunc.AggregateSum(SqlFunc.IIF(x2.Id > 0, 1, 0)), //null的数据要为0所以不能用count
                        date = x1.ColumnName.ToString("yyyy-MM")
                    }
                    ).ToList().OrderBy(c => c.date)
                    .ToList();

                    var queryableLeft1 = resultlist.Sum(c => c.count);
                    int years1Count = db.Queryable<Operateinfo>().Count(c =>
                 (c.Operate_time.Year == 2022 && c.Operate_time.Month == 1)
                 || (c.Operate_time.Year == 2021 && c.Operate_time.Month == 1)
                 || (c.Operate_time.Year == 2020 && c.Operate_time.Month == 1)
                 || (c.Operate_time.Year == 2019 && c.Operate_time.Month == 1)
                 || (c.Operate_time.Year == 2018 && c.Operate_time.Month == 1)
                 || (c.Operate_time.Year == 2017 && c.Operate_time.Month == 1)
                 || (c.Operate_time.Year == 2016 && c.Operate_time.Month == 1)
                 || (c.Operate_time.Year == 2015 && c.Operate_time.Month == 1)
                 || (c.Operate_time.Year == 2014 && c.Operate_time.Month == 1)
                 || (c.Operate_time.Year == 2013 && c.Operate_time.Month == 1));
                }


            }
        }
        #endregion
    }
}

